#ifndef _ILINEBLOCK_H_
#define _ILINEBLOCK_H_

#include <BLine>
#include <BPainter>
#include <BTextFormat>
#include "ICodeCell.h"

namespace BWE
{
	class ILineBlock
	{
	public:
		ILineBlock();
		ILineBlock(const ILineBlock& other);
		~ILineBlock();

		inline void setFont(const BFont* font)
		{
			if (_font != font)
			{
				_font = font;
			}
			dirtyFont = true;
			dirtyCells = true;
		}
		inline const BFont* font() const
		{
			return _font;
		}

		inline void clear()
		{
			text.clear();
			reset();
		}
		inline bool empty() const
		{
			return cells.empty();
		}
		inline int tail() const
		{
			if (cells.last().code == '\n')
				return cells.size() - 1;
			return cells.size();
		}

		void reset();
		void reset(const BString& text);
		void append(const BString& text);
		bool remove(int pos, int count = 1);
		bool input(const BCode& code);
		bool input(const BString& text);
		inline void flushText()
		{
			text.reset();
			for (int i = 0; i < cells.size(); i++)
			{
				text.append(cells[i].code);
			}
		}

		BString substr(int pos, int count) const;
		BString selection() const;

		bool selectWord();
		bool removeSelection();

		bool seekHead();
		bool seekPoint(const BPoint& point);
		bool seekTail();

		int seekPrevCode();
		int seekNextCode();
		int seekPrevWord();
		int seekNextWord();

		int indexAt(const BPoint& pos) const;
		int wordWidth(int index) const;

		void adjust(int width);
		void paint(BPainter& painter, BTextFormat* format = 0);

	public:
		bool				visible;
		BRect				rect;
		Align				align;
		BRange				range;
		BString				text;
		BSize				textSize;
		BArray<CodeCell>	cells;
		bool				dirtyCells;
		bool				dirtyFont;
		int					rowHeight;
		int					inputIndex;
		int					inputCount;
		BHolder<const BFont>	_font;
	};

	typedef BList<ILineBlock>			ILineBlockList;
	typedef ILineBlockList::iterator	ILineBlockIterator;

}

#endif